#include "adas_data_unpack.hh"

using namespace std;

int main(int argc, char **argv)
{
    //-f get file name
    string file_name;
    //-L
    int LSB = 15;
    //-i
    int asic_num = 16;
    //-w
    bool is_write_txt = false;
    //-b
    bool is_base_data = false;
    //-O
    string save_path_set = "unpack_result";
    //-s
    bool is_extra_trigger = false;
    //-m
    bool is_set_same_rms = false;
    //-n number of sigmas as threshold
    int thresh_limit = 3;

    while ((c = getopt(argc, argv, "f:L:i:O:n:bsm")) != EOF)
    {
        switch (c)
        {
        case 'f':
            file_name = optarg;
            break;
        case 'L':
            LSB = atoi(optarg);
            break;
        case 'i':
            asic_num = atoi(optarg);
            break;
        case 'b':
            is_base_data = true;
            break;
        case 'O':
            save_path_set = optarg;
            break;
        case 'n':
          thresh_limit = atoi(optarg);
          break;
        case 's':
            is_extra_trigger = true;
            break;
        case 'm':
            is_set_same_rms = true;
            break;
        case '?':
            cout << cRED;
            cout << "<<---------------------->>" << endl;
            cout << "[Error]: unknow parameters" << endl;
            cout << "<<---------------------->>" << endl;
            cout << "Or forget break in the last case?" << endl;
            show_info(argv[0]);
            return -1;
            break;
        default:
            break;
        }
    }

    if (file_name.empty() || LSB == 0)
    {
        cout << cRED;
        cout << "<<---------------------->>" << endl;
        cout << "[Error]: missing parameters" << endl;
        cout << "<<---------------------->>" << endl;
        show_info(argv[0]);
        return -1;
    }
    if (file_name.find(".dat") == string::npos)
    {
        cout << cRED;
        cout << "<<---------------------->>" << endl;
        cout << "[Error]: file name is not correct" << endl;
        cout << "<<---------------------->>" << endl;
        show_info(argv[0]);
        return -1;
    }

    for (int i = 0; i < 20; i++)
    {
        cout << "==";
    }
    cout << endl;
    cout << "Begin process:" << endl;
    cout << endl;

    vector<string> file_name_path = split_string(file_name, "/");
    string save_path;
    if (file_name_path[1].empty())
    {
        save_path = "./" + save_path_set;
    }
    else
    {
        save_path = file_name_path[1] + "/" + save_path_set;
    }
    if (stat(save_path.c_str(), &info) == -1)
    {

        cout << cYELLOW << "Save path : " << save_path << " does not exist, create it." << cRESET << endl;
        fs::create_directories(save_path);
    }

    string relative_filename = file_name_path[0];
    vector<string> data_file_prefix = split_string(relative_filename, ".dat");

    string root_file_name = save_path + data_file_prefix[1];
    string initial_file_name = save_path + data_file_prefix[1] + "_" + "init.txt";
    string plot_file_name = save_path + data_file_prefix[1] + "_";

    string save_suffix;
    vector<string> file_name_suffix = split_string(data_file_prefix[1], "-");
    save_suffix = "link" + file_name_suffix[0];

    string file_write = save_path + "/" + "3sigma_vth_" + save_suffix + "_usb" + ".txt";

    double adc_LSB = LSB * 0.15492 * 2.048 * 0.001;
    vector<uint32_t> initial_data;

    unpack_process unpack_process(file_name, asic_num, root_file_name, is_write_txt, is_base_data, is_set_same_rms, adc_LSB, thresh_limit, plot_file_name, file_write, is_extra_trigger);

    cout << endl;
    cout << cBLUE << "Done!" << cRESET << endl;
    cout << endl;
    return 0;
}

void show_info(char *name)
{
    cout << cCYAN;
    for (int i = 0; i < 15; i++)
    {
        cout << "==";
    }
    cout << endl
         << "Usage: " << name << " -[parameter] [options]" << endl
         << "    -f [First data filename. If single file, specific the filename] (required input parameter)" << endl
         << "    -L [LSB of the ADADS1128. Default is 15](required input parameter)" << endl
         << "    -i [Number of asic. Default is 6](required input parameter)" << endl
         << "    -w [write txt]" << endl
         << "    -b [data is base data]" << endl
         << "    -O [Save path. Default: unpack_result](required input parameter)" << endl
         << "    -s [Extra trigger]" << endl
         << "    -m [Set same rms]" << endl
         << cRESET << endl;
}

vector<string> split_string(const string &str, string delims, int inc)
{
    std::vector<std::string> result;
    size_t i = str.rfind(delims, str.length());
    if (i == str.length() - 1 || i == string::npos)
    {
        result.push_back(str);
    }
    else
    {
        result.push_back(str.substr(i + inc, str.length() - i));
        result.push_back(str.substr(0, i));
    }
    return result;
}
